//
// Created by gogoqiu on 2022/3/23.
//

#ifndef RAPIDSVN_CMAKE_BASESETTINGSFRAME_H
#define RAPIDSVN_CMAKE_BASESETTINGSFRAME_H

#include "base.h"
#include "wx/wx.h"
#include "SqliteQueryEngine.h"
#include "wx/vector.h"
#include "BaseItem.h"
#include "../controls/InputDialog.h"
/*
struct KeyControlInterface{
protected:
    //uuid
    //key
    wxString _key;
public:
    void set_id( const wxString& id ){
        this->_key = id;
    }
    wxString get_id(){
        return _key;
    }
};

class IdCheckBox: public KeyControlInterface, public wxCheckBox{

};

class IdTextControl: public KeyControlInterface, public wxTextCtrl{

};
*/

//class BaseSettingsFrame;

//how to parse
struct ViewChoiceData{
    int chosen;
    wxArrayString choices;
};

class ListItemPanel: public wxPanel{
    //
    void OnSwitchLeftClick( wxMouseEvent& event ){
        //checkbox onclick callback, set value true
        auto* checkBox = (wxCheckBox*)valueControl;
        //event.GetEventUserData()
        if( checkBox->IsChecked() ){
            checkBox->SetValue( false );
            checkBox->SetLabel("false");
            item->setValue("false");
        }else{
            checkBox->SetValue( true );
            checkBox->SetLabel("true");
            item->setValue("true");
        }
        //checkBox->Thaw();
        UpdateExist();
    }

    void OnInputClickItem( wxMouseEvent& event ){
        ShowInputDialog();
    }

    void ShowInputDialog(){
        //input callback, set the parent to this
        //if ok, set the callback
        auto *dialog = new InputDialog( this, item );
        if (dialog->ShowModal() == wxID_OK) {
            UpdateExist( );
        }
    }

    void OnListClickItem( wxMouseEvent& event );
    ViewChoiceData choiceData;
protected:
    BaseItem *item;
    wxControl* valueControl;
    wxBoxSizer* innerSizer;
    SqliteQueryEngine* engine;
public:
    //parent:
    ListItemPanel( wxWindow *parent, SqliteQueryEngine* engine, BaseItem *item ):
            wxPanel( parent ) {
        this->item = item;
        this->engine = engine;
        SetBackgroundColour( wxColour( 0, 128, 192 ) );
        innerSizer = new wxBoxSizer( wxVERTICAL );

        switch (item->getType()) {
            case PT_LIST:
                BuildListValueControlGroup();
                break;
            case PT_SWITCH: {
                BuildSwitchValueControlGroup();
                break;
            }
            case PT_INPUT:{
                BuildTextValueControlGroup();
                break;
            }
        }
        innerSizer->Add( BuildDescription(), 1,
                         wxALL | wxALIGN_LEFT, 10);
        SetSizer( innerSizer );
        Layout();
    }

    void UpdateExist(  );

    //void UpdateList();

    wxStaticText* BuildPrompt(){
        return new wxStaticText(this, wxID_ANY, item->getPrompt(),
                                           wxDefaultPosition, wxDefaultSize, 0);
    }

    wxStaticText* BuildDescription(){
        return new wxStaticText(this, wxID_ANY, item->getDescription(),
                                wxDefaultPosition, wxDefaultSize, 0);
    }

    //prompt and staticText
    void BuildTextValueControlGroup(){
        SetBackgroundColour(wxColour(0, 128, 192));
        auto *_innerSizer = new wxBoxSizer(wxHORIZONTAL);

        _innerSizer->Add( BuildPrompt(), 1,
                        wxALL | wxALIGN_LEFT, 10);
        //last updated value
        auto *statusCtrl = new wxStaticText(this, wxID_ANY, item->getValue(),
                                            wxDefaultPosition, wxDefaultSize, 0);
        //statusCtrl->SetBackgroundColour( wxColour( 0, 255, 0 ) );
        valueControl = statusCtrl;
        _innerSizer->Add(statusCtrl, 1,
                        wxALL | wxALIGN_CENTER_HORIZONTAL, 4);
        //wxPanel::SetSizer
        //this->SetSizer(innerSizer);
        //Layout();
        //panel connect
        innerSizer->Add(_innerSizer);
        this->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler(ListItemPanel::OnInputClickItem ),
                new MyObj( item ), this );
    }

    //prompt and checkbox
    void BuildSwitchValueControlGroup(){
        SetBackgroundColour(wxColour(0, 128, 192));
        //auto *innerSizer = new wxBoxSizer(wxVERTICAL);
        auto *_innerSizer = new wxBoxSizer(wxHORIZONTAL);

        _innerSizer->Add( BuildPrompt(), 1,
                        wxALL | wxALIGN_LEFT, 10);
        //last updated value
        auto *choiceCtrl = new wxCheckBox( this, wxID_ANY,
                                           item->getValue(), wxDefaultPosition, wxDefaultSize, 0 );
        valueControl = choiceCtrl;
        if( item->getValue().IsSameAs("true")){
            choiceCtrl->SetValue(true );
        } else
            choiceCtrl->SetValue(false );
        _innerSizer->Add( choiceCtrl, 1,
                        wxALL | wxALIGN_CENTER_HORIZONTAL, 4);
        innerSizer->Add(_innerSizer);
        //SetSizer(innerSizer);
        //Layout();
        //
        choiceCtrl->Connect( wxEVT_LEFT_DOWN, wxMouseEventHandler(ListItemPanel::OnSwitchLeftClick ),
                            new MyObj( item ), this );
    }

    int parseSelections( const wxString& s );

    /*
     *
     */
    void BuildListValueControlGroup(){
        SetBackgroundColour(wxColour(0, 128, 192));
        auto *_innerSizer = new wxBoxSizer(wxHORIZONTAL);
        _innerSizer->Add( BuildPrompt(), 1,
                         wxALL | wxALIGN_LEFT, 10);
        //
        //wxString selectedValue;
        //wxArrayString choices;
        //find selected
        int selectIndex = parseSelections( item->getValue() );
        if( selectIndex<0 ){
            wxMessageBox( wxString::Format("列表数据解析异常, 返回值: %d, KEY: %s, VALUE: %s",
                                           selectIndex,
                                           item->getKey(), item->getValue() ),
                          wxT("异常"), wxICON_ERROR );
            return;
        }
        auto *choiceCtrl = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choiceData.choices, 0 );

        choiceCtrl->SetSelection( selectIndex );
        valueControl = choiceCtrl;
        _innerSizer->Add( choiceCtrl, 1,
                         wxALL | wxALIGN_CENTER_HORIZONTAL, 4);
        //SetSizer(innerSizer);
        innerSizer->Add(_innerSizer);
        choiceCtrl->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxMouseEventHandler(ListItemPanel::OnListClickItem ),
                             new MyObj( item ), this );
    }
};

/*
 * keys
 */
class BaseSettingsFrame: public wxFrame, public SettingInterface{
private:
    void OnClickItem( wxMouseEvent& event );
protected:
    //
    wxScrolledWindow* m_listbox{};
    SqliteQueryEngine* engine;
    wxString appId;
    //std::tuple()
    /*
     * controls
     */
    wxVector<BaseItem*> items;
    //void buildView();
    wxVector<ListItemPanel*> controls;
    ListItemPanel* FindControl( const wxString& key );
public:
    //
    explicit BaseSettingsFrame( wxWindow *parent, const wxString& appId );
    int loadAll() override;
    //virtual void collectAllKeys() = 0;
    virtual void BuildView();
    virtual int setup();
    //virtual void buildView();
    int UpdateItem( const wxString& key, const wxString& value );
    int UpdateItem( BaseItem * item );
};


#endif //RAPIDSVN_CMAKE_BASESETTINGSFRAME_H
